﻿/* HEADER
 * ------
 * © 2009 by Salomon Zwecker 
 * modified by:
 * - 
 */
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Shapes.Geometry;

namespace Shapes.Misc.Appearance
{
    /// <summary>
    /// A Mask for a brush which initially should become a dashd line.
    /// Surprisingly it became something different which looks nice with some kind of Shapes.
    /// </summary>
    public class BrushMaskStrangeEffect : BrushMask
    {
        private List<float> _Steps = new List<float>();
        private float _StepsLength;

        /// <summary>
        /// Creates a new Strange effect
        /// </summary>
        /// <param name="step1">a step defining the thickness of a visible part</param>
        /// <param name="step2">a step defining the thickness of an invisible part</param>
        /// <param name="furtherSteps">(optional) append as many further steps as you want</param>
        public BrushMaskStrangeEffect(float step1, float step2, params float[] furtherSteps)
        {
            _Steps.Add(step1);
            _Steps.Add(step2);

            _StepsLength = step1 + step2;

            foreach (float step in furtherSteps)
                AddStep(step);
        }

        /// <summary>
        /// Adds another step which is invisible if the step before was visible or the other way around
        /// </summary>
        /// <param name="step">the thickness</param>
        public void AddStep(float step)
        {
            _Steps.Add(step);
            _StepsLength += step;
        }

        internal override void ModifyScaleFactor(ref Vector2 scale)
        {
            // don't change the scale factor
        }

        internal override float GetVisibilityValue(Brush brush, Drawing geometry, ref Vector2 localPosition, ref float distance, ref float? t)
        {
            if(t == null)
            {
                //Vector2 pos = geometry.GetNearestPointOnEdge(ref localPosition);
                t = geometry.GetEdgePathValueFromPoint(ref localPosition);
            }
            float path = (geometry.BorderLength * (float) t) % _StepsLength;

            float cur = 0;
            bool isVisible = true;
            foreach(float f in _Steps)
            {
                cur += f;

                if(path <= cur)
                {
                    return (isVisible) ? 1 : 0;
                }
                isVisible = !isVisible;
            }
            return 0.5f;
        }
    }
}
